#ifndef GRID_H
#define GRID_H

#ifndef FACILITY_H
#include "../Facility/Facility.h"
#endif

#ifndef SHAPE_H
#include "../Cargo/Shape.h"
#endif

#ifndef HEAD_H
#include "head.h"
#endif

#ifndef DATA_MANAGER_H
#include "../utils/data_manager.h"
#endif

/****************************
 *                          *
 * @brief 实现格子的类       *
 *                          *
 ****************************/
class Box
{
    Facility *master;       // 建在该格子上的设施 没有就为nullptr
    Object_Qt * object_qt = null; // 矿物的贴图
public:
    Box(Facility *m = null);
    /// @brief 格子的析构,当且仅当游戏结束时 发生,
    /// 并且不会对两个指针进行析构， 这两个指针指向的是Cargo模板，使用的是栈内存
    ~Box();
    inline void link_obj(Object_Qt * obj){
        object_qt = obj;
    }
    friend class Grid;
    friend class GameLogic;
};

/****************************
 *                          *
 * @brief 实现地图的类       *
 *                          *
 ****************************/
class Grid
{
    friend class Map_Data_Manager;
    friend class GameLogic;
    int height, width; // 高度 和 宽度
    std::vector<std::vector<Box>> grids;
    const Data_Manager *data_manager;
public:
    /// @brief
    Grid(int height = grid::HEIGHT, int width = grid::WIDTH);
    bool CanPlace(const Coordinate& co, int w, int h);
    std::unordered_set<Facility *> setFacility(Facility *facility, const Coordinate& co, int w, int h); // 返回需要清理的设备
    std::unordered_set<Facility *> surroundingFacilities(const Coordinate& co, int w, int h); // 返回周围的设备
    inline Box& operator[](const Coordinate &co){
        return grids[co.x][co.y];
    }
    inline Box operator[](const Coordinate &co) const {
        return grids[co.x][co.y];
    }
    inline bool isValid(int i, int j){
        switch(data_manager->getGridProgress()){
        case 0:
            return width / 3 <= i && i < 2 * width / 3 && height / 3 <= j && j < 2 * height / 3;
        case 1:
            return width / 4 <= i && i < 3 * width / 4 && height / 4 <= j && j < 3 * height / 4;
        case 2:
        default:
            return 0 <= i && i < width && 0 <= j && j < height;
        }

    }
    inline char get_cargo(int i, int j){
        return this->data_manager->getGrid()[i][j];
    }
    inline Box& getBox(int i, int j){
        return this->grids[i][j];
    }

    /// @brief 地图的析构,当且仅当游戏结束时 发生。
    ~Grid();
};
#endif //GRID_H
